package cn.jetpiece.cloud.system.dp.app.modular.biz.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.jetpiece.cloud.core.page.PageFactory;
import cn.jetpiece.cloud.core.util.HttpContext;
import cn.jetpiece.cloud.core.util.MD5Util;
import cn.jetpiece.cloud.jwt.utils.JwtTokenUtil;
import cn.jetpiece.cloud.model.exception.ServiceException;
import cn.jetpiece.cloud.model.page.PageResult;
import cn.jetpiece.cloud.model.response.Result;
import cn.jetpiece.cloud.starter.app.modular.base.controller.BaseController;
import cn.jetpiece.cloud.system.dp.api.biz.DpTOpenApi;
import cn.jetpiece.cloud.system.dp.api.biz.model.params.OpenApiParam;
import cn.jetpiece.cloud.system.dp.api.biz.model.params.ProjectAddParam;
import cn.jetpiece.cloud.system.dp.api.biz.model.result.DpTApiResult;
import cn.jetpiece.cloud.system.dp.api.biz.model.result.DpTProjectResult;
import cn.jetpiece.cloud.system.dp.app.consts.CommonConstant;
import cn.jetpiece.cloud.system.dp.app.core.aop.annotion.Permission;
import cn.jetpiece.cloud.system.dp.app.modular.biz.entity.DpTApi;
import cn.jetpiece.cloud.system.dp.app.modular.biz.entity.DpTApp;
import cn.jetpiece.cloud.system.dp.app.modular.biz.entity.DpTProject;
import cn.jetpiece.cloud.system.dp.app.modular.biz.entity.DpTScopeData;
import cn.jetpiece.cloud.system.dp.app.modular.biz.service.IDpTApiService;
import cn.jetpiece.cloud.system.dp.app.modular.biz.service.IDpTAppService;
import cn.jetpiece.cloud.system.dp.app.modular.biz.service.IDpTProjectService;
import cn.jetpiece.cloud.system.dp.app.modular.biz.service.IDpTScopeDataService;
import cn.jetpiece.cloud.system.dp.app.modular.biz.wrapper.DpTApiOutWrapper;
import cn.jetpiece.cloud.system.dp.app.modular.biz.wrapper.DpTApiWrapper;
import cn.jetpiece.cloud.system.dp.app.modular.biz.wrapper.DpTProjectWrapper;
import cn.jetpiece.cloud.system.dp.app.utils.JwtUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.nio.charset.Charset;
import java.util.*;

/**
 * dp_open_api
 *
 * @author jetpiece
 * @since 2023-05-15
 */
@Slf4j
@RestController
public class DpTOpenApiController extends BaseController<DpTApp, IDpTAppService> implements DpTOpenApi {

    @Autowired
    private IDpTProjectService dpTProjectService;

    @Autowired
    private IDpTApiService dpTApiService;

    @Autowired
    private IDpTScopeDataService dpTScopeDataService;

    @Override
    public Result<Map<String, Object>> auth(@Valid OpenApiParam param) {
        String appKey = param.getParams().getStr("appKey");
        String appSecret = param.getParams().getStr("appSecret");
        if (StringUtils.isBlank(appKey) || StringUtils.isBlank(appSecret)) {
            throw new ServiceException(400, "参数校验异常");
        }
        DpTApp app = this.service.getByAppKey(appKey);
        if (ObjectUtil.isNull(app)) {
            throw new ServiceException(400, "参数校验异常");
        }
        String appEncrypeSecret = MD5Util.MD5Encode(app.getAppSecret(), Charset.defaultCharset().name());
        if (!appEncrypeSecret.equals(appSecret)) {
            throw new ServiceException(400, "未授权密匙");
        }
        String token = JwtUtil.sign(app.getAppKey(), app.getAppSecret());
        Map<String, Object> tokenInfo = new HashMap<>();
        tokenInfo.put("token", token);
        tokenInfo.put("expiredDate", JwtUtil.getExpirationDateFromToken(token));
        return Result.OK(tokenInfo);
    }

    @Override
    public Result<PageResult<DpTApiResult>> queryAuthSynchApiSet() {
        String token = HttpContext.getRequest().getHeader(CommonConstant.AUTHORIZATION);
        if(StringUtils.isBlank(token)){
            throw new ServiceException(400, "未授权访问");
        }
       boolean isExpired = JwtTokenUtil.getINSTANCE().isTokenExpired(token);
        if(isExpired){
            throw new ServiceException(400, "token认证失效");
        }
        String appKey = JwtUtil.getUsername(token);
        QueryWrapper<DpTApi> queryWrapper = new QueryWrapper();
        if(StringUtils.isNotBlank(appKey)){
            DpTScopeData scopeData = dpTScopeDataService.getByAppKey(appKey);
            if (scopeData != null && org.apache.commons.lang3.StringUtils.isNotBlank(scopeData.getApiValue())) {
                List<String> apiList = new ArrayList<>();
                apiList.addAll(Arrays.asList(scopeData.getApiValue().split(",")));
                queryWrapper.in("id", apiList);
            }else{
                return this.defaultApiPageResult();
            }
        }
        Page<DpTApi> page = PageFactory.defaultPage();
        IPage<DpTApi> pageList = dpTApiService.page(page, queryWrapper);
        return Result.OK(new DpTApiOutWrapper(pageList).setWrapper(true).wrapPageResult());
    }

    @Override
    public Result<PageResult<DpTProjectResult>> queryAuthProjectSet() {
        String token = HttpContext.getRequest().getHeader(CommonConstant.AUTHORIZATION);
        if(StringUtils.isBlank(token)){
            throw new ServiceException(400, "未授权访问");
        }
        boolean isExpired = JwtTokenUtil.getINSTANCE().isTokenExpired(token);
        if(isExpired){
            throw new ServiceException(400, "token认证失效");
        }
        String appKey = JwtUtil.getUsername(token);
        QueryWrapper<DpTProject> queryWrapper = new QueryWrapper();
        if(StringUtils.isNotBlank(appKey)){
            DpTScopeData scopeData = dpTScopeDataService.getByAppKey(appKey);
            if (scopeData != null && org.apache.commons.lang3.StringUtils.isNotBlank(scopeData.getProjectValue())) {
                List<String> projectList = new ArrayList<>();
                projectList.addAll(Arrays.asList(scopeData.getProjectValue().split(",")));
                queryWrapper.in("project_id", projectList);
            }else{
                return this.defaultPageResult();
            }
        }
        Page<DpTProject> page = PageFactory.defaultPage();
        IPage<DpTProject> pageList = dpTProjectService.page(page, queryWrapper);
        return Result.OK(new DpTProjectWrapper(pageList).setWrapper(true).wrapPageResult());
    }

    @Override
    public Result<String> syncOmsProject(@Valid ProjectAddParam param) {
        return dpTProjectService.projectInfo(param);
    }

    private Result<PageResult<DpTProjectResult>> defaultPageResult() {
        return Result.OK(new DpTProjectWrapper(PageFactory.defaultPage()).setWrapper(true).wrapPageResult());
    }

    private Result<PageResult<DpTApiResult>> defaultApiPageResult() {
        return Result.OK(new DpTApiWrapper(PageFactory.defaultPage()).setWrapper(true).wrapPageResult());
    }

}
